home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / PowerPlant / CVersCaption 1.3.1 / CVersCaption.cp < prev    next >
Encoding:
Text File  |  1997-07-12  |  11.5 KB  |  465 lines  |  [TEXT/CWIE]

  1. /*******************************************************************************\
  2. |                                                                                |
  3. |  CVersCaption.cp ©1997 John C. Daub.  All rights reserved                        |
  4. |                                                                                |
  5. |  See the file "CVersCaption README" for full details, instructions, changes,    |
  6. |  licensing agreement, etc.  Due to the important information included in that    |
  7. |  file, if you did not receive a copy of it, please contact the author for        |
  8. |  a copy.                                                                        |
  9. |                                                                                |
  10. |  John C. Daub <mailto:hsoi@eden.com>                                            |
  11. |  <http://www.eden.com/~hsoi/>  <http://www.eden.com/~hsoi/prog.html>            |
  12. |                                                                                |
  13. \*******************************************************************************/
  14.  
  15.  
  16. #ifdef PowerPlant_PCH
  17. #include PowerPlant_PCH
  18. #endif
  19.  
  20. #include "CVersCaption.h"
  21.     
  22. #include <LString.h>
  23. #include <UException.h>
  24. #include <LStream.h>
  25. #include <UDrawingUtils.h>
  26. #include <UTextTraits.h>
  27. #include <UMemoryMgr.h>
  28.  
  29.  
  30. #if ( __PowerPlant__ < 0x01608000 ) // version 1.6/CW11
  31.  
  32. //========================================================================
  33. //    •    CreateFromStream                        [public, static]
  34. //========================================================================
  35. //    Only compiled if the RegisterClass_() macro doesn't exist.  Saves a bit
  36. //    of space in and of itself, plus keeps down redundancy.
  37.  
  38. CVersCaption*
  39. CVersCaption::CreateFromStream(
  40.     LStream *inStream )
  41. {
  42. #ifdef DEBUG_NEW
  43.     return ( NEW CVersCaption( inStream ) );
  44. #else
  45.     return ( new CVersCaption( inStream ) );
  46. #endif
  47.  
  48. }
  49.  
  50. #endif
  51.  
  52.  
  53. //========================================================================
  54. //    • CVersCaption                                [public]
  55. //========================================================================
  56. // Default constructor
  57.  
  58. CVersCaption::CVersCaption()
  59.     : mVersion( 0x0000 ),
  60.     mUseShortString( false ),
  61.     mUseCountryCode( false )
  62. {
  63.     mText = "\p";
  64.     
  65.     InitVersCaption();
  66. }
  67.  
  68.  
  69. //========================================================================
  70. //    • CVersCaption                                [public]
  71. //========================================================================
  72. // Copy constructor
  73.  
  74. CVersCaption::CVersCaption(
  75.     const CVersCaption &inOriginal )
  76.         : LCaption( inOriginal ),
  77.         mVersion( inOriginal.mVersion ),
  78.         mUseShortString( inOriginal.mVersion ),
  79.         mUseCountryCode( inOriginal.mUseCountryCode )
  80. {
  81.     // there's no need to call InitVersCaption() here since we
  82.     // should already have this information
  83. }
  84.  
  85.  
  86. //========================================================================
  87. //    • operator=                                    [public]
  88. //========================================================================
  89. //    Assignment operator
  90.  
  91. CVersCaption&    
  92. CVersCaption::operator=(
  93.     const CVersCaption &inOriginal )
  94. {
  95.     // check for self-assignment
  96.     if ( this == &inOriginal ) {
  97.         return *this;
  98.     }
  99.     
  100.     LCaption::operator=(inOriginal);
  101.     mVersion = inOriginal.mVersion;
  102.     mUseShortString = inOriginal.mUseShortString;
  103.     mUseCountryCode = inOriginal.mUseCountryCode;
  104.     
  105.     // LCaption doesn't explictly provide its own assignment operator,
  106.     // so to not risk losing vital data, we'll (re)assign here.
  107.     
  108.     //mText = inOriginal.mText;
  109.     SetDescriptor( mText );
  110.     SetTextTraitsID( inOriginal.mTxtrID );
  111.     
  112.     return *this;
  113. }
  114.  
  115.  
  116. //========================================================================
  117. //    • CVersCaption                                [public]
  118. //========================================================================
  119. // Parameterized constructor
  120.  
  121. CVersCaption::CVersCaption(
  122.     const SPaneInfo        &inPaneInfo,
  123.     ConstStringPtr        inString,
  124.     ResIDT                inTextTraitsID,
  125.     Boolean                inUseShortString,
  126.     Boolean                inUseCountryCode )
  127.         : LCaption( inPaneInfo, inString, inTextTraitsID ),
  128.         mVersion( 0x0000 ),
  129.         mUseShortString( inUseShortString ),
  130.         mUseCountryCode( inUseCountryCode )
  131. {
  132.     mText = "\p";
  133.     
  134.     InitVersCaption();
  135. }
  136.  
  137.  
  138. //========================================================================
  139. //    • CVersCaption                                [public]
  140. //========================================================================
  141. // LStream constructor
  142.  
  143. CVersCaption::CVersCaption(
  144.     LStream *inStream )
  145.         : LCaption( inStream ),
  146.         mVersion( 0x0000 )
  147. {
  148.     mText = "\p";
  149.     
  150.     inStream->ReadData( &mUseShortString, sizeof(Boolean) );
  151.     inStream->ReadData( &mUseCountryCode, sizeof(Boolean) );
  152.     
  153.     InitVersCaption();
  154. }
  155.  
  156.  
  157. //========================================================================
  158. //    • ~CVersCaption                                [public, virtual]
  159. //========================================================================
  160. // Destructor
  161.  
  162. CVersCaption::~CVersCaption()
  163. {
  164.     // nothing
  165. }
  166.  
  167.  
  168. //========================================================================
  169. //    • InitVersCaption                            [private]
  170. //========================================================================
  171. //
  172. //    Private initializer of the object
  173. //
  174. //    Gets the 'vers' #1 resource resource.  Return 0 if resource missing.
  175. //    Convert resource's NumVersion (see Types.h) to the version "string"
  176. //
  177. //    This does assume that the application's resource fork is the current
  178. //    resource file.  If it is not and/or a 'vers' #1 resource doesn't
  179. //    exist, unpredictable results can occur.
  180.  
  181. void
  182. CVersCaption::InitVersCaption()
  183. {
  184.     //    Get the 'vers' 1 resource
  185.     
  186.     Handle    versH = ::GetResource( 'vers', 1 );
  187.  
  188.     if ( versH == nil ) {
  189.         
  190.         OSErr err = ::ResError();
  191.     
  192.         // shouldn't need more than a signal...this is such a
  193.         // vital part of a complete application and something that
  194.         // you're bound to forget...so I doubt it will fail in the
  195.         // real world cause you SHOULD catch this before you ship.
  196.  
  197.         // actually, I've heard that GetResource() will never produce
  198.         // resNotFound (so of course, check for the nil handle).
  199.         // this error handler might want to be revamped for later
  200.         // (but really, you should have a 'vers' 1 resource in your app
  201.         // anyways...the only reason I could then see it failing would
  202.         // be from a memFullErr or something)
  203.         
  204.         if ( err == resNotFound ) {
  205.             SignalPStr_( "\p'vers' #1 resource not found" );
  206.             return; // so we don't crash
  207.         }
  208.     
  209.         // but just in case (e.g. memFullErr or something), we'll
  210.         // prepare
  211.         
  212.         ThrowIfOSErr_(err);
  213.     }
  214.     
  215.     // if they wish to use the short string (VersRec.shortVersion), we'll just
  216.     // extract that and return (1.2 addition)
  217.     
  218.     if ( GetUseShortString() ) {
  219.     
  220.         // (just for sanity, if mUseShortString == true, mUseCountryCode
  221.         // doesn't really matter)
  222.     
  223.         mText += (*(VersRecHndl)versH)->shortVersion;
  224.         ::ReleaseResource(versH);
  225.         
  226.         return;
  227.     }
  228.     
  229.     // if they wish to print the coutry code, let's extract out the code
  230.     // right now.  we'll get the string in a bit. (1.2 addition)
  231.     
  232.     Int16    theCountryCode;
  233.     
  234.     if ( GetUseCountryCode() ) {
  235.         theCountryCode = (*(VersRecHndl)versH)->countryCode;
  236.     }
  237.     
  238.     // if not, we'll continue....    
  239.         
  240.     // copy out the version information
  241.     
  242.     SetVersion( *((Uint32 *)(*versH)) );
  243.         
  244.     // we can dump the 'vers' resource
  245.     
  246.     if ( versH ) {
  247.         ::ReleaseResource( versH );
  248.         versH = nil;
  249.     }
  250.     
  251.     
  252.     // set ver1-3, relStatus, prerelNum from the version info.
  253.     // Note that the first two bytes are in an unusual format.
  254.     
  255.     Uchar    ver1,
  256.             ver2,
  257.             ver3,
  258.             relStatus, 
  259.             prerelNum;
  260.  
  261.     ver1 = ((Uchar *)&mVersion)[0];
  262.     ver1 = (((ver1 & 0xF0 ) >> 4) * 10) + (ver1 & 0x0F);
  263.     ver2 = (((Uchar *)&mVersion)[1] & 0xF0) >> 4;
  264.     ver3 = (((Uchar *)&mVersion)[1] & 0x0F);
  265.     relStatus = ((Uchar *)&mVersion)[2];
  266.     prerelNum = ((Uchar *)&mVersion)[3];
  267.     prerelNum = (((prerelNum & 0xF0 ) >> 4) * 10) + (prerelNum & 0x0F); // 1.1 fix
  268.     
  269.     // Insert v1 and v2 into our version string
  270.     
  271.     Str255    tmpStr;
  272.     StringHandle dotH;
  273.     
  274.     ::NumToString((Int32)ver1, tmpStr );
  275.     LString::AppendPStr( mText, tmpStr );
  276.     
  277.     dotH = ::GetString( STR_dot );
  278.     ThrowIfResFail_(dotH);
  279.  
  280.     {
  281.         // not really needed, but can't hurt to be safe
  282.         StHandleLocker lock((Handle)dotH);
  283.         
  284.         LString::AppendPStr( mText, *dotH );
  285.         
  286.         ::NumToString( (Int32)ver2, tmpStr );
  287.         LString::AppendPStr( mText, tmpStr );
  288.         
  289.         // to make it nicer, we only print the third number if it's non-zero.
  290.         
  291.         // if you always want all three matches, remove the if statement
  292.         
  293.         if ( ver3 ) {
  294.             LString::AppendPStr( mText, *dotH );
  295.             
  296.             ::NumToString( (Int32)ver3, tmpStr );
  297.             LString::AppendPStr( mText, tmpStr );
  298.         }
  299.     }
  300.     
  301.     ::ReleaseResource((Handle)dotH);
  302.     dotH = nil;
  303.     
  304.     
  305.     // if the release status is development, alpha or beta, add
  306.     // a 'd', 'a', or 'b' to our version string.
  307.     // if you do something like "GM" or "FC1/FC2/etc" before you
  308.     // ship a product, you could add in another case here for that
  309.     // and then just conditionally wrap it with preprocessor macros
  310.     // to be compiled out when you #define __DEBUG__ to false (or
  311.     // whatever debugger macros are turned off).
  312.     
  313.     StringHandle relH;
  314.     
  315.     switch( relStatus ) {
  316.  
  317.         case 0x20: {
  318.             
  319.             // development
  320.             relH = ::GetString(STR_devel);
  321.             ThrowIfResFail_(relH);
  322.             break;
  323.         }
  324.         
  325.         case 0x40: {
  326.  
  327.             // alpha
  328.             relH = ::GetString(STR_alpha);
  329.             ThrowIfResFail_(relH);
  330.             break;
  331.         }
  332.         
  333.         case 0x60: {
  334.  
  335.             // beta
  336.             relH = ::GetString(STR_beta);
  337.             ThrowIfResFail_(relH);
  338.             break;
  339.         }
  340.         
  341.         case 0x80: {
  342.             
  343.             // nothing
  344.             
  345.             break;
  346.         }
  347.         
  348.         default: {
  349.         
  350.             // it'd be odd if we hit the default, so we'll signal
  351.             // for possible error
  352.             
  353.             SignalPStr_("\pUnknown relStatus" );
  354.             break;
  355.         }
  356.     }
  357.     
  358.     // if we've added a 'd', 'a', or 'b', print the
  359.     // pre-release number at the end.
  360.     
  361.     if ( relStatus != 0x80 ) {
  362.         
  363.         {
  364.             StHandleLocker lock((Handle)relH);
  365.             LString::AppendPStr(mText,*relH);
  366.         }
  367.  
  368.         if (relH) {
  369.             ::ReleaseResource((Handle)relH); 
  370.             relH = nil;
  371.         }
  372.  
  373.         ::NumToString( (Int32)prerelNum, tmpStr );
  374.         LString::AppendPStr( mText, tmpStr );
  375.     }
  376.     
  377.     // lastly, if we want to use the country code, let's stick that
  378.     // on.
  379.     
  380.     if ( GetUseCountryCode() ) {
  381.  
  382.         Str255    countryStr;
  383.         ::GetIndString( countryStr, STRx_countries, theCountryCode + 1 );
  384.         LString::AppendPStr( mText, countryStr );
  385.     }
  386.     
  387. }
  388.  
  389.  
  390. //========================================================================
  391. //    • ActivateSelf                            [protected, virtual]
  392. //========================================================================
  393. //
  394. //    We need to force a redraw when the pane becomes active so that it
  395. //    will draw properly.
  396.  
  397. void
  398. CVersCaption::ActivateSelf()
  399. {
  400.     if ( mActive == triState_On ) {
  401.         Refresh();
  402.     }
  403. }
  404.  
  405.  
  406. //========================================================================
  407. //    • DeactivateSelf                        [protected, virtual]
  408. //========================================================================
  409. //
  410. //    We need to force a redraw when the pane becomes deactivated
  411.  
  412. void
  413. CVersCaption::DeactivateSelf()
  414. {
  415.     if ( mActive == triState_Off || mActive == triState_Latent ) {
  416.         Refresh();
  417.     }
  418. }
  419.  
  420.  
  421. //========================================================================
  422. //    • DrawSelf                                [protected, virtual]
  423. //========================================================================
  424. //
  425. //    Similar to LCaption::DrawSelf, but if the pane isn't active, the
  426. //    text is drawn in a "dimmed" state.
  427.  
  428. void
  429. CVersCaption::DrawSelf()
  430. {
  431.     Rect    frame;
  432.     CalcLocalFrameRect(frame);
  433.     
  434.     Int16    just = UTextTraits::SetPortTextTraits(mTxtrID);
  435.     
  436.     RGBColor    textColor;
  437.     ::GetForeColor(&textColor);
  438.     
  439.     ApplyForeAndBackColors();
  440.     
  441.     if ( !IsActive() ) {
  442.  
  443.         // lighten the text color a bit
  444.         
  445.         textColor.red = textColor.red + 65535 >> 1;
  446.         textColor.green = textColor.green + 65535 >> 1;
  447.         textColor.blue = textColor.blue + 65535 >> 1;
  448.     }    
  449.     
  450.     ::RGBForeColor(&textColor);
  451.     
  452.     UTextDrawing::DrawWithJustification((Ptr)&mText[1], mText[0], frame, just);
  453. }
  454.  
  455.  
  456. // the following functions are declared inline in the header file. The #pragma
  457. // mark let's them show up in the CW IDE's function popup for ease of navigation
  458. // and reference. :-)
  459.  
  460. #pragma mark CVersCaption::GetVersion
  461. #pragma mark CVersCaption::SetVersion
  462. #pragma mark CVersCaption::GetUseShortString
  463. #pragma mark CVersCaption::SetUseShortString
  464. #pragma mark CVersCaption::GetUseCountryCode
  465. #pragma mark CVersCaption::SetUseCountryCode